package com.foreveross.crawl.common.domain;

import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import com.foreveross.crawl.common.InstanceFactory;
import com.foreveross.crawl.common.jpa.IBaseRepository;
import com.foreveross.crawl.common.jpa.annontation.HBaseColumn;
import com.foreveross.crawl.common.util.JsonUtil;
/**
 * hbase实体基类
 *  @author xiangsf 2013-2-16
 *
 */
public abstract class BaseHBaseEntity extends BaseEntity {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8227836577259237059L;
	
	private static final Logger logger = Logger.getLogger(BaseHBaseEntity.class);

	@Override
	public IBaseRepository getBaseEntityRepository() {
		return (IBaseRepository)InstanceFactory.getInstance("entityHBaseRepository");
	}
	/**
	 * hbase的rowkey生成
	 * @return
	 */
	public abstract String generateRowKey();

	@Override
	public IBaseEntity get(Serializable id) {
		return getBaseEntityRepository().get(this.getClass(), id);
	}

	@Override
	public boolean exists(Serializable id) {
		return getBaseEntityRepository().exists(this.getClass(), id);
	}

	@Override
	public List<? extends BaseEntity> findAll() {
		return getBaseEntityRepository().findAll(this.getClass());
	}

	@Override
	public void create() {
		getBaseEntityRepository().create(this);
	}

	@Override
	public void update() {
		getBaseEntityRepository().update(this);
	}

	@Override
	public void delete() {
		getBaseEntityRepository().delete(this);
	}

	@Override
	public void save() {
		getBaseEntityRepository().save(this);
	}
	
	protected <T> String convertJson(T bean){
		Class clazz = bean.getClass();
//		Field[] fields = clazz.getDeclaredFields();
		List<Field> fields = getField(bean);
		StringBuilder sb = new StringBuilder("");
		sb.append("{");
		
		for(Field field : fields){
			String key = field.getName();
			boolean flag = false;
			HBaseColumn hbase = field.getAnnotation(HBaseColumn.class);
			if(hbase == null) continue;
			Object value = null;
			Type type = null;
			String format = null;
			boolean fDate = false;
			StringBuffer sbufer = new StringBuffer("");
			try {
				PropertyDescriptor pd = new PropertyDescriptor(key, clazz);
				Method getMethod = pd.getReadMethod();
				value = getMethod.invoke(bean);
				type = field.getGenericType();
				if(type.toString().contains("List")){
					value = JsonUtil.toJson((List)value);
					flag = true;
				} else if(type.toString().contains("Set")){
					value = JsonUtil.toJson((Set)value);
					flag = true;
				} else if(type.toString().contains("Date")){
					format = hbase.format();
					if(value != null && format != null && !format.equals("")){
						value = com.foreveross.crawl.common.util.DateUtil.formatDay((Date)value, format);
					}
					fDate = true;
				}
			}catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
			if(hbase != null){
				key = hbase.family() + "|" + hbase.qualifier();
				value = (value == "null" || value == null) ? "" : value;
				if (flag) {
					sb.append("\"").append(key).append("\":").append(value)
							.append(",");
				} else {
					sb.append("\"").append(key).append("\":").append("\"")
							.append(value).append("\"").append(",");
				}

			}
		}
		sb.deleteCharAt(sb.lastIndexOf(","));
		sb.append("}");
		return sb.toString();
	}
	
	protected <T> String fromObject(T bean){
		return JsonUtil.toJson(bean, new String[]{"id", "baseEntityRepository", "planeInfoEntity"});
	}
	
	private <T> List<Field> getField(T bean){
		List<Field> retList = new ArrayList<Field>();
		Class clazz = bean.getClass();
		Field[] fields = clazz.getDeclaredFields();
		Field[] fieldSuper = clazz.getDeclaredFields();
		Class superClazz = clazz.getSuperclass();
		fieldSuper = superClazz.getDeclaredFields();
		addFieldToList(fields, retList);
		addFieldToList(fieldSuper, retList);
		return retList;
	}
	
	private void addFieldToList(Field[] fs, List<Field> listField){
		if(fs != null && fs.length != 0){
			for(Field f : fs){
				listField.add(f);
			}
		}
	}
}
